﻿/*
Digraph (library for building, traversal, comparison and saving of directed
graph).

Copyright (C) 2014 Dmitry Merzagitovich Arslanov

This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option) any
later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*/

// How to save objects of custom digraph types in tgf.

namespace CustomTypes3
{
    using System;
    using System.ComponentModel;
    using System.Globalization;

    // Define node type with converter.
    [TypeConverter(typeof(NodeConverter))]
    public class Node
    {
        public string Name { get; set; }

        public double Value { get; set; }

        public Node(string name, double value)
        {
            Name = name;
            Value = value;
        }
    }

    // Provide string converter for node type.
    public class NodeConverter : TypeConverter
    {
        // Can convert from node to string.
        public override bool CanConvertTo(ITypeDescriptorContext context,
                                          Type destinationType)
        {
            return destinationType == typeof(string);
        }

        // Can convert from string to node.
        public override bool CanConvertFrom(ITypeDescriptorContext context,
                                            Type sourceType)
        {
            return sourceType == typeof(string);
        }

        // Convert from node to string.
        public override object ConvertTo(ITypeDescriptorContext context,
                                         CultureInfo culture,
                                         object value,
                                         Type destinationType)
        {
            Node node = value as Node;
            return string.Format("Name={0};Value={1}", node.Name, node.Value);
        }

        // Convert from string to node.
        public override object ConvertFrom(ITypeDescriptorContext context,
                                           CultureInfo culture,
                                           object value)
        {
            string str = value as string;
            string[] records = str.Split(';');
            string nodeName = string.Empty;
            double nodeValue = 0.0;
            foreach (string record in records)
            {
                string[] args = record.Split('=');
                if (string.IsNullOrEmpty(nodeName)) nodeName = args[1];
                else nodeValue = double.Parse(args[1]);
            }
            return new Node(nodeName, nodeValue);
        }
    }
}

namespace Sample9
{
    using CustomTypes3;
    using System;
    using System.Windows;

    using Vertex = Digraph.Vertex<CustomTypes3.Node, System.Windows.Vector>;
    using Builder = Digraph.Builder<CustomTypes3.Node, System.Windows.Vector>;

    public static class App
    {
        public static void Main()
        {
            // Create digraph.
            Builder builder = new Builder();
            Vertex v1 = builder.NewVertex(new Node("v1", 1.0));
            Vertex v2 = builder.NewVertex(new Node("v2", 2.0));
            Vertex v3 = builder.NewVertex(new Node("v3", 3.0));
            builder.NewArc(v1, v2, new Vector(1.0, 0.0));
            builder.NewArc(v2, v3, new Vector(0.0, 1.0));
            // Save in file.
            builder.Digraph.Save("digraph.tgf");
            // Load it back.
            Builder loadedBuilder = Builder.Load("digraph.tgf");
            // Print loaded digraph.
            Console.WriteLine(loadedBuilder.Digraph.ToString());
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

#region Content of digraph.tgf is shown below in comments:
/*
1 Name=v1;Value=1
2 Name=v2;Value=2
3 Name=v3;Value=3
#
1 2 1,0
2 3 0,1
*/
#endregion
